from collections import Counter

from django.shortcuts import render

# Create your views here.
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import AllowAny, BasePermission
from rest_framework.response import Response
from rest_framework.views import APIView

from course.models import *
from course.serializers import *


class MyBasePermission(BasePermission):
    def has_permission(self, request, view):
        """判断用户对模型有没有访问权"""
        if request.user.is_superuser:
            # 管理员可以随意添加和读取
            return True
        perms = {
            'create': request.data.get('user') == str(request.user.id),
            'list': request.query_params.get('user') == str(request.user.id),
            'destroy': view.get_object().user.id == request.user.id,
            'retrieve': view.get_object().user.id == request.user.id
        }
        return perms.get(view.action, False)


class PageNum(PageNumberPagination):
    page_size_query_param = 'page_size'


class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseDeepSerializer

    permission_classes = (AllowAny,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('attention', 'learner', 'create_time')

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('title', 'desc', 'status', 'course_type', 'course_tag')

    # 自定义分页器 覆盖全局配置
    pagination_class = PageNum

    def get_serializer_class(self):
        if self.action == 'list':
            return CourseSerializer
        else:
            return CourseDeepSerializer


class CourseTypeViewSet(viewsets.ModelViewSet):
    queryset = CourseType.objects.all()
    serializer_class = CourseTypeSerializer


class CourseTagViewSet(viewsets.ModelViewSet):
    queryset = CourseTag.objects.all()
    serializer_class = CourseTagSerializer


class ChaptersViewSet(viewsets.ModelViewSet):
    queryset = Chapters.objects.all()
    serializer_class = ChaptersSerializer


class SectionsViewSet(viewsets.ModelViewSet):
    queryset = Sections.objects.all()
    serializer_class = SectionsSerializer


class FollowViewSet(viewsets.ModelViewSet):
    queryset = Follow.objects.all()
    serializer_class = FollowSerializer

    permission_classes = (MyBasePermission,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('create_time',)

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('user',)

    # 自定义分页器 覆盖全局配置
    pagination_class = PageNum


class PathViewSet(viewsets.ModelViewSet):
    queryset = Path.objects.all()

    def get_serializer_class(self):
        if self.action == 'list':
            return PathSerializer
        else:
            return PathDeepSerializer


class JieDuanViewSet(viewsets.ModelViewSet):
    queryset = JieDuan.objects.all()
    serializer_class = JieDuanSerializer


class UserCourseViewSet(viewsets.ModelViewSet):
    queryset = UserCourse.objects.all()
    serializer_class = UserCourseSerializer

    permission_classes = (MyBasePermission,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('create_time',)

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('user',)

    # 自定义分页器 覆盖全局配置
    pagination_class = PageNum


class UserSectionsViewSet(viewsets.ModelViewSet):
    queryset = UserSections.objects.all()
    serializer_class = UserSectionsSerializer

    permission_classes = (MyBasePermission,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('create_time',)

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('user', 'course')

    # 自定义分页器 覆盖全局配置
    pagination_class = PageNum


# 关注课程
class AddFollow(APIView):
    def post(self, request):
        # 取参数 userid,  course id, action : 取消/关注
        uid = request.user.id  # 用户id
        cid = request.data.get('cid')  # 课程id
        action = request.data.get('action')  # '1': 关注, 0是取消
        # 修改 follow表, 修改 课程关注人数
        if action == '1':
            # 关注
            try:
                follow = Follow.objects.get(user_id=uid, course_id=cid)
            except Exception as e:
                follow = None
            if follow:
                return Response({"code": 0, "msg": "关注成功"})
            else:
                follow = Follow(user_id=uid, course_id=cid)
                follow.save()
                follow.course.follower += 1
                follow.course.save()
                return Response({"code": 0, "msg": "关注成功"})

        else:
            # 取消
            follow = Follow.objects.get(user_id=uid, course_id=cid)
            follow.course.follower -= 1
            follow.course.save()
            follow.delete()
            return Response({"code": 0, "msg": "取消关注成功"})

        # 返回结果


# 播放记录
class AddPlayHistory(APIView):
    def post(self, request):
        # 1. 获取用户, 获取小节id
        user = request.user
        sid = request.data.get('sid')
        section = Sections.objects.get(id=sid)
        course = section.chapters.course

        # 2. 保存播放记录
        try:
            us = UserSections.objects.get(user=user, course=course, section=section)
        except Exception as e:
            us = None
        if us:
            us.save()  # 更新updatetime
            return Response({"code": 0, "msg": "添加播放记录成功"})
        else:
            us = UserSections(user=user, course=course, section=section)
            us.save()
            return Response({"code": 0, "msg": "添加播放记录成功"})


# 课程推荐
class RecoCourse(APIView):
    def get(self, request):
        # 获取课程id
        course_id = int(request.GET.get('course_id', 0))
        # 查询学过该课程的用户的记录
        uc = UserCourse.objects.filter(course_id=course_id)
        user_ids = set()  # 所有学过这个课程的用户
        for i in uc:
            user_ids.add(i.user.id)

        course_ids = []  # 所有课程的id的序列:  [1,2,3,1,2,1,3,....]
        for uid in user_ids:
            uc = UserCourse.objects.filter(user_id=uid)
            for i in uc:
                if i.course.id != course_id:
                    course_ids.append(i.course.id)

        counts = Counter(course_ids)
        most_course = counts.most_common(1)  # [(1,3),(2,2),....]
        most_course_id = [k for k, v in most_course]  # [1,2,3,...]
        course_list = Course.objects.filter(id__in=most_course_id)
        course_ser = CourseSerializer(course_list, many=True)

        return Response({'code': 0, 'msg': '查询成功', 'data': {'courses': course_ser.data}})


class CommentReplyViewSet(viewsets.ModelViewSet):
    queryset = CommentReply.objects.all()
    serializer_class = CommentReplySerializer

    permission_classes = (MyBasePermission,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('create_time',)

    # 指定过滤字段, 不设置, 过滤功能不起效
    # filter_fields = ('user', 'course')

    # 自定义分页器 覆盖全局配置
    # pagination_class = PageNum


class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

    permission_classes = (MyBasePermission,)

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('create_time',)

    # 指定过滤字段, 不设置, 过滤功能不起效
    # filter_fields = ('user', 'course')

    # 自定义分页器 覆盖全局配置
    # pagination_class = PageNum


class CommentSelfView(APIView):
    def get(self, request):
        # 获取课程评论
        # 1. 获取课程id
        course_id = request.GET.get('course_id')
        # 一级评论
        comments = CommentSelf.objects.filter(course_id=course_id, father__isnull=True)
        # 2. 组织数据
        comment_list = []
        for comm in comments:  # 所有的评论,  一部分是没有father, 一部分有father
            comm_dict = get_comment_str(comm)
            comment_list.append(comm_dict)
        # 3. 返回
        return Response({'code': 0, 'msg': '查询成功', 'data': comment_list})


def get_comment_str(comment):
    # 这个方法, 序列化评论, 递归方法
    data = {
        'username': comment.user.username,
        'userimg': comment.user.img.url,
        'content': comment.content,
        'time': comment.update_time,
        'children': []
    }

    if comment.children:
        for comm in comment.children.all():
            children = get_comment_str(comm)
            data['children'].append(children)
    return data
